package org.jasig.cas.ticket.registry;

import org.jasig.cas.ticket.Ticket;
import org.jasig.cas.ticket.TicketGrantingTicket;
import org.jasig.cas.util.PropertiesUtils;
import org.springframework.beans.factory.annotation.Value;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Collection;


/*
 *  TicketRegistry using Redis, to solve CAS Cluster.
 *  
 *  @author ZL
 * 
 */

public class RedisTicketRegistry_bak extends AbstractDistributedTicketRegistry {


    public static int redisDatabaseNum;
    public static String hosts;
    public static int port;
    public static int st_time;  //ST最大空闲时间
    public static int tgt_time; //TGT最大空闲时间
    public static JedisPool cachePool;

    static {
        redisDatabaseNum = PropertiesUtils.getPropertyInt("redis.database.num");
        hosts = PropertiesUtils.getProperty("redis.hosts");
        port = PropertiesUtils.getPropertyInt("redis.port");
        st_time = PropertiesUtils.getPropertyInt("redis.st_time");
        tgt_time = PropertiesUtils.getPropertyInt("redis.tgt_time");
        cachePool = new JedisPool(new JedisPoolConfig(), hosts, port);
    }

    public void addTicket(Ticket ticket) {

        Jedis jedis = cachePool.getResource();
        jedis.select(redisDatabaseNum);

        int seconds = 0;

        String key = ticket.getId() ;

        if(ticket instanceof TicketGrantingTicket){
            seconds = tgt_time/1000;
        }else{
            seconds = st_time/1000;
        }

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = null;
        try{
            oos = new ObjectOutputStream(bos);
            oos.writeObject(ticket);

        }catch(Exception e){
            logger.error("adding ticket to redis error.");
        }finally{
            try{
                if(null!=oos) oos.close();
            }catch(Exception e){
                logger.error("oos closing error when adding ticket to redis.");
            }
        }
        jedis.set(key.getBytes(), bos.toByteArray());
        jedis.expire(key.getBytes(), seconds);

        cachePool.returnResource(jedis);

    }

    public Ticket getTicket(final String ticketId) {
        return getProxiedTicketInstance(getRawTicket(ticketId));
    }


    private Ticket getRawTicket(final String ticketId) {

        if(null == ticketId) return null;

        Jedis jedis = cachePool.getResource();
        jedis.select(redisDatabaseNum);

        Ticket ticket = null;
        byte[] bytes = jedis.get(ticketId.getBytes());

        if(bytes==null){
            return null;
        }

        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        ObjectInputStream ois = null;

        try{
            ois = new ObjectInputStream(bais);
            ticket = (Ticket)ois.readObject();
        }catch(Exception e){
            logger.error("getting ticket to redis error.");
        }finally{
            try{
                if(null!=ois)  ois.close();
            }catch(Exception e){
                logger.error("ois closing error when getting ticket to redis.");
            }
        }

        cachePool.returnResource(jedis);

        return ticket;
    }



    public boolean deleteTicket(final String ticketId) {

        if (ticketId == null) {
            return false;
        }

        Jedis jedis = cachePool.getResource();
        jedis.select(redisDatabaseNum);

        jedis.del(ticketId.getBytes());

        cachePool.returnResource(jedis);

        return true;
    }

    public Collection<Ticket> getTickets() {

        throw new UnsupportedOperationException("GetTickets not supported.");

    }

    protected boolean needsCallback() {
        return false;
    }

    protected void updateTicket(final Ticket ticket) {
        addTicket(ticket);
    }
}
